import type { WebContents } from 'electron'
import { createWriteStream, readFile } from 'node:fs'
import { basename } from 'node:path'
import { fileURLToPath } from 'node:url'
import { dialog, net } from 'electron'

/**
 * 下载图片并保存到用户选择的路径
 */
export async function saveImageAsFromURL(webContents: WebContents, srcURL: string): Promise<void> {
  // 推断默认文件名
  let defaultName = 'image'
  try {
    const u = new URL(srcURL)
    const name = basename(decodeURIComponent(u.pathname))
    if (name) defaultName = name
  } catch {
    // ignore
  }

  const { canceled, filePath } = await dialog.showSaveDialog({
    title: '图片另存为',
    defaultPath: defaultName,
    filters: [
      { name: 'Images', extensions: ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'ico', 'svg'] },
      { name: 'All Files', extensions: ['*'] }
    ]
  })
  if (canceled || !filePath) return

  const buf = await fetchImageBuffer(srcURL)
  if (!buf) throw new Error('下载图片失败')

  await new Promise<void>((resolve, reject) => {
    const ws = createWriteStream(filePath)
    ws.on('finish', () => resolve())
    ws.on('error', reject)
    ws.write(buf)
    ws.end()
  })
}

/**
 * 获取图片二进制（支持 data:, http/https:, file:）
 */
export async function fetchImageBuffer(srcURL: string): Promise<Buffer | null> {
  try {
    if (srcURL.startsWith('data:')) {
      const base64 = srcURL.split(',')[1]
      return Buffer.from(base64, 'base64')
    }

    if (srcURL.startsWith('file:')) {
      const path = fileURLToPath(srcURL)
      return await new Promise<Buffer>((resolve, reject) => {
        readFile(path, (err, data) => (err ? reject(err) : resolve(data)))
      })
    }

    // http/https 通过 electron.net 下载
    return await new Promise<Buffer>((resolve, reject) => {
      const request = net.request(srcURL)
      const chunks: Buffer[] = []
      request.on('response', response => {
        response.on('data', (chunk: Buffer) => chunks.push(chunk))
        response.on('end', () => resolve(Buffer.concat(chunks)))
        response.on('error', reject)
      })
      request.on('error', reject)
      request.end()
    })
  } catch (error) {
    console.error('下载图片失败:', error)
    return null
  }
}
